import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.io.*;
import javax.swing.*;

/**
 *This program is a client-sever chat utility that can also be used 
 *for file sharing with the use of Local Area Network, base program were 
 *created by Abhishek Kumar Verma and Tousif Khan
 *@link visit www.techzoo.org 
 *@link visit abhishek27.wordpress.com
 *<p>
 *The ChatServer is the initial step in the code that creates a server
 *for the utility, without this, there would be no connection to the client.
 *
 *@author Pecson, Andrien
 *@author Dela Cruz, Jeremy Ashley
 *@author Rocafort, Julienne Micah
 *@author Tugade, Joanna Mae
 *
 **/
public class ChatServer {
	/**Instantiation of objects**/
	private static final int PORT = 9001;
    private static HashSet<String> names = new HashSet<String>();
    private static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();
    
    /**
	 *The Listen method intantiates a new server socket that
	 *gets the value of PORT, which is 9001, and starts the server
	 *to be able to connect and chat.
	 *@exception Exception
	 *
	 **/
    public static void listen() throws Exception {
        JOptionPane.showMessageDialog(null, "Server Started Successfully");

        ServerSocket listener = new ServerSocket(PORT);
        try {
            while (true) {
                new Handler(listener.accept()).start();
            }
        } finally {
            listener.close();
        }
    }

    /**
	 *The Handler class handles the connection and enabling of the chat utility
	 *to the server. 
	 *@see Threads
	 *
	 **/
    private static class Handler extends Thread {
        private String name;
        private Socket socket;
        private BufferedReader in;
        private PrintWriter out;

		 /**Contructor method for Handler
		  *@param socket sets the socket with the class variable socket
		  *@see Socket
		  *
		  **/
        public Handler(Socket socket) {
            this.socket = socket;
        }
        
		/**
		*The run method allows the server(once there's a connection) to write and chat with its client.
		*@exception IOException exception handling upon the input of the user
		*@see BufferedReader
	 	*@see PrintWriter
		*
		**/	
        public void run() {
            try {
                in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);

                while (true) {
                    out.println("SUBMITNAME");
                    name = in.readLine();
                    if (name == null) {
                        return;
                    }
                    synchronized (names) {
                        if (!names.contains(name)) {
                            names.add(name);
                            break;
                        }
                    }
                }

                out.println("NAMEACCEPTED");
                writers.add(out);

                while (true) {
                    String input = in.readLine();
                    if (input == null) {
                        return;
                    }
                    for (PrintWriter writer : writers) {
                        writer.println("MESSAGE " + name + ": " + input);
                    }
                }
            } catch (IOException e) {
                System.out.println(e);
            } finally {
                if (name != null) {
                    names.remove(name);
                }
                if (out != null) {
                    writers.remove(out);
                }
                try {
                    socket.close();
                } catch (IOException e) {
                }
            }
        }
    }


}